﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.IO;
using System.Diagnostics;
using System.Xml.Linq;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Threading;

namespace WP7_calendar.Model
{
    /// <summary>
    /// Data model for single day view
    /// </summary>
    public class Day : INotifyPropertyChanged
    {
        private string m_selectedDate;
        public string SelectedDate 
        {
            get { return m_selectedDate; }
            set
            {
                m_selectedDate = value;
                LoadItems();
            }
        }
        private WebStorage.Facebook m_Facebook;

        public DateTime DisplayAgenda { get; set;}
        public ObservableCollection<AgendaItem> AgendaItems { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;

        public Day(DateTime selectedDate)
        {
            AgendaItems = new ObservableCollection<AgendaItem>();
            SelectedDate = selectedDate.ToString().Substring(0,9);
            m_Facebook = new WebStorage.Facebook();

            AgendaItems.CollectionChanged += AgendaItems_CollectionChanged;
        }

        /// <summary>
        /// Opens a xml file and loads the containing data into the Day calendar, not thouroghly tested on account of difficulty generating accessible data
        /// </summary>
        private void LoadItems()
        {
            Debug.WriteLine("Entering LoadItems");
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication()) //Open Isolated storage
            {
                try
                {
                    if (AgendaItems.Count != 0) AgendaItems.Clear();
                    string fileName = SelectedDate.Replace('/', ',') + ".xml";
                    if (isf.FileExists(fileName)) // Check if file exists
                    {
                        Debug.WriteLine(fileName);
                        using (IsolatedStorageFileStream stream = isf.OpenFile(fileName, FileMode.Open)) //Open file
                        {
                            XElement appData = XElement.Load(stream);
                            foreach (XElement item in appData.Elements("app")) // Read from file
                            {
                                // Add all items to list
                                AgendaItems.Add(new AgendaItem(item.Element("header").Value, SelectedDate, item.Element("time").Value, item.Element("location").Value));
                            }
                        }
                    }
                }
                catch (FileNotFoundException e)
                {
                    Debug.WriteLine(e.Message);
                }
            }
        }

        /// <summary>
        /// Saves current Agendalist and reloads it to the screen
        /// </summary>
        public void SaveItem()
        {
                using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    string fileName = AgendaItems[0].Date.Replace('/',',') + ".xml"; // fx. 12,10,2011.xml contains all appointments for October 12th 2011

                    using (IsolatedStorageFileStream stream = isf.OpenFile(fileName, FileMode.OpenOrCreate)) // open file
                    {
                        XDocument document = new XDocument(new XElement("apps"));

                        foreach (AgendaItem item in AgendaItems) // Generate a new XML file
	                    {
                            XElement[] values = new XElement[] { new XElement("header", item.Header), new XElement("time", item.Time), new XElement("location", item.Location) };
                            XElement app = new XElement("app");
                            app.Add(values);
                            document.Element("apps").Add(app);
	                    }
                        document.Save(stream); // Write new file to isolated storage, overwriting old file if such exists
                    }
                }
                LoadItems(); // Reload the list to memory, updating the UI
        }

        /// <summary>
        /// Taken of the internet(http://stackoverflow.com/questions/1294307/silverlight-tabcontrol-bound-to-observablecollectionstring-not-updating-when-co)
        /// Author: Jhon Dhom
        /// Does the real work involved in raising the ProperyChangedEvent neccessary to having the UI update
        /// </summary>
        private void NotifyPropertyChanged(string info)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                foreach (PropertyChangedEventHandler d in handler.GetInvocationList())
                {
                    d(this, new PropertyChangedEventArgs(info));
                }
            }
        }

        /// <summary>
        /// Event handler, forcing all databindings to be re-evaluated
        /// </summary>
        private void AgendaItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            NotifyPropertyChanged("AgendaItems");
        }

        public void UpdateFacebook()
        {
            m_Facebook.Update();

            foreach (AgendaItem item in m_Facebook.Result)
            {
                Day day = new Day(DateTime.Parse(item.Date));
                day.LoadItems();
                day.AgendaItems.Add(item);
                day.SaveItem();
            }

            LoadItems();
        }
    }
}
